This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

#basketball shotchart analysis
library(BasketballAnalyzeR)
Loading required package: ggplot2
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2

If you want to reproduce the figures contained in the book of
Zuccolotto and Manisera (2020) and
if the version of your R machine is >= 3.6.0, you need to type
RNGkind(sample.kind = "Rounding")
at the beginning of your working session
#basketball shotchart analysis
library(BasketballAnalyzeR)
PbP <- PbPmanipulation(PbP.BDB)
head(PbP)




{# for stephen curry} subdata <- subset(PbP, player=="Stephen Curry") subdata$xx <- subdata$original_x/10 subdata$yy <- subdata$original_y/10-41.75

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

#basketball shotchart analysis
library(BasketballAnalyzeR)
Loading required package: ggplot2
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2

If you want to reproduce the figures contained in the book of
Zuccolotto and Manisera (2020) and
if the version of your R machine is >= 3.6.0, you need to type
RNGkind(sample.kind = "Rounding")
at the beginning of your working session
#basketball shotchart analysis
library(BasketballAnalyzeR)
PbP <- PbPmanipulation(PbP.BDB)
head(PbP)

PbP <- PbPmanipulation(PbP.BDB)
PbP <- PbPmanipulation(PbP.BDB)
table(PbP$team)

        ATL   BKN   BOS   CHA   CHI   CLE   DAL   DEN   DET   GSW   HOU   IND   LAC   LAL   MEM   MIA   MIL 
 3075   422   451   459   421   428   439   816   837   401 17096   640   397   879   869   638   382   365 
  MIN   NOP   NYK   OKC   ORL   PHI   PHX   POR   SAC   SAS   TOR   UTA   WAS 
  619   857   396   919   395   437   828   630   778   837   427   859   433 
subdata <- subset(PbP, team == "GSW")
net <- assistnet(subdata)
net <- assistnet(subdata)
net$assistTable
                  player
assist             Andre Iguodala Damian Jones David West Draymond Green JaVale McGee Jordan Bell
  Andre Iguodala                0            0         18             20            7           5
  Damian Jones                  0            0          0              0            0           0
  David West                    8            0          0             21            1           1
  Draymond Green               18            2         36              0           16          15
  JaVale McGee                  2            0          0              3            0           3
  Jordan Bell                   3            1          3              6           10           0
  Kevin Durant                  7            3         14             44           22          23
  Kevon Looney                  6            0          0              3            4           1
  Klay Thompson                14            1         31             18           11           4
  Nick Young                    0            0          5              1            4           2
  Omri Casspi                   5            0          5              1            2           1
  Patrick McCaw                 2            0         12              6            5           3
  Quinn Cook                    6            2          4              4            9          12
  Shaun Livingston              6            0         33             19            3           3
  Stephen Curry                14            0          3             54           18           9
  Zaza Pachulia                 5            0          0             16            0           3
                  player
assist             Kevin Durant Kevon Looney Klay Thompson Nick Young Omri Casspi Patrick McCaw Quinn Cook
  Andre Iguodala             30            8            37         20           9             4          3
  Damian Jones                0            2             0          0           0             0          0
  David West                 12            1            38         15          13             7          0
  Draymond Green            125            5           132         21           3             8         15
  JaVale McGee                0            6             6          2           0             2          2
  Jordan Bell                16            5             9         11           8            12         12
  Kevin Durant                0           12            83         15          19             9         19
  Kevon Looney                6            0             2          6           1             4          3
  Klay Thompson              30            5             0          4          13             2          1
  Nick Young                  3            2             7          0           5             1          1
  Omri Casspi                 9            3             8          3           0             5          3
  Patrick McCaw               8            1            14         14           5             0          3
  Quinn Cook                 12            6            13          8           0             3          0
  Shaun Livingston           10            6            27         18           4             3          1
  Stephen Curry              65           14            68         20           9             8          0
  Zaza Pachulia              16            1            31          2           8             2          3
                  player
assist             Shaun Livingston Stephen Curry Zaza Pachulia
  Andre Iguodala                  9            34             6
  Damian Jones                    0             0             0
  David West                     19             2             0
  Draymond Green                 24            66            23
  JaVale McGee                    0             7             0
  Jordan Bell                     1             1             4
  Kevin Durant                   13            56            27
  Kevon Looney                    2             4             0
  Klay Thompson                  11            17            23
  Nick Young                      1             3             1
  Omri Casspi                     2             2             2
  Patrick McCaw                   3             3             2
  Quinn Cook                      2             1             7
  Shaun Livingston                0             6             1
  Stephen Curry                   1             0            26
  Zaza Pachulia                   3            19             0
net$nodeStats
net$assistNet
 Network attributes:
  vertices = 16 
  directed = TRUE 
  hyper = FALSE 
  loops = FALSE 
  multiple = FALSE 
  bipartite = FALSE 
  total edges= 202 
    missing edges= 0 
    non-missing edges= 202 

 Vertex attribute names: 
    vertex.names 

 Edge attribute names: 
    N 
net$assistNet
 Network attributes:
  vertices = 16 
  directed = TRUE 
  hyper = FALSE 
  loops = FALSE 
  multiple = FALSE 
  bipartite = FALSE 
  total edges= 202 
    missing edges= 0 
    non-missing edges= 202 

 Vertex attribute names: 
    vertex.names 

 Edge attribute names: 
    N 
set.seed(123)
plot(net,
     node.size='ASTPTS',
     node.col='FGPTS_AST')
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.

plot(net,
     node.size='ASTPTS',
     node.col='FGPTS_AST',
     layout = 'circle',
     edge.thr = 20)
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.


# NBA Team & Player Performance Analysis

library(BasketballAnalyzeR)
# Teams
str(Tbox)
'data.frame':   30 obs. of  23 variables:
 $ Team: chr  "Atlanta Hawks" "Boston Celtics" "Brooklyn Nets" "Charlotte Hornets" ...
 $ GP  : int  82 82 82 82 82 82 82 82 82 82 ...
 $ MIN : int  3941 3961 3971 3956 3971 3946 3961 3976 3961 3946 ...
 $ PTS : int  8475 8529 8741 8874 8440 9091 8390 9020 8509 9304 ...
 $ W   : int  24 55 28 36 27 50 24 46 39 58 ...
 $ L   : int  58 27 54 46 55 32 58 36 43 24 ...
 $ P2M : int  2213 2202 2095 2373 2264 2330 2161 2398 2322 2583 ...
 $ P2A : int  4471 4483 4190 4873 4736 4314 4354 4566 4756 4611 ...
 $ P2p : num  49.5 49.1 50 48.7 47.8 ...
 $ P3M : int  917 939 1041 824 906 981 967 940 886 926 ...
 $ P3A : int  2544 2492 2924 2233 2549 2636 2688 2536 2373 2369 ...
 $ P3p : num  36 37.7 35.6 36.9 35.5 ...
 $ FTM : int  1298 1308 1428 1656 1194 1488 1167 1404 1207 1360 ...
 $ FTA : int  1654 1697 1850 2216 1574 1909 1530 1830 1621 1668 ...
 $ FTp : num  78.5 77.1 77.2 74.7 75.9 ...
 $ OREB: int  743 767 792 827 790 694 666 902 830 691 ...
 $ DREB: int  2693 2878 2852 2901 2873 2761 2717 2748 2756 2877 ...
 $ AST : int  1946 1842 1941 1770 1923 1916 1858 2059 1868 2402 ...
 $ TOV : int  1276 1149 1245 1041 1147 1126 1007 1227 1103 1265 ...
 $ STL : int  638 604 512 559 626 582 578 627 628 655 ...
 $ BLK : int  348 373 390 373 289 312 310 404 317 612 ...
 $ PF  : int  1606 1618 1688 1409 1571 1524 1578 1533 1508 1607 ...
 $ PM  : int  -447 294 -307 21 -577 77 -249 121 -12 490 ...
# Teams
str(Tbox)
'data.frame':   30 obs. of  23 variables:
 $ Team: chr  "Atlanta Hawks" "Boston Celtics" "Brooklyn Nets" "Charlotte Hornets" ...
 $ GP  : int  82 82 82 82 82 82 82 82 82 82 ...
 $ MIN : int  3941 3961 3971 3956 3971 3946 3961 3976 3961 3946 ...
 $ PTS : int  8475 8529 8741 8874 8440 9091 8390 9020 8509 9304 ...
 $ W   : int  24 55 28 36 27 50 24 46 39 58 ...
 $ L   : int  58 27 54 46 55 32 58 36 43 24 ...
 $ P2M : int  2213 2202 2095 2373 2264 2330 2161 2398 2322 2583 ...
 $ P2A : int  4471 4483 4190 4873 4736 4314 4354 4566 4756 4611 ...
 $ P2p : num  49.5 49.1 50 48.7 47.8 ...
 $ P3M : int  917 939 1041 824 906 981 967 940 886 926 ...
 $ P3A : int  2544 2492 2924 2233 2549 2636 2688 2536 2373 2369 ...
 $ P3p : num  36 37.7 35.6 36.9 35.5 ...
 $ FTM : int  1298 1308 1428 1656 1194 1488 1167 1404 1207 1360 ...
 $ FTA : int  1654 1697 1850 2216 1574 1909 1530 1830 1621 1668 ...
 $ FTp : num  78.5 77.1 77.2 74.7 75.9 ...
 $ OREB: int  743 767 792 827 790 694 666 902 830 691 ...
 $ DREB: int  2693 2878 2852 2901 2873 2761 2717 2748 2756 2877 ...
 $ AST : int  1946 1842 1941 1770 1923 1916 1858 2059 1868 2402 ...
 $ TOV : int  1276 1149 1245 1041 1147 1126 1007 1227 1103 1265 ...
 $ STL : int  638 604 512 559 626 582 578 627 628 655 ...
 $ BLK : int  348 373 390 373 289 312 310 404 317 612 ...
 $ PF  : int  1606 1618 1688 1409 1571 1524 1578 1533 1508 1607 ...
 $ PM  : int  -447 294 -307 21 -577 77 -249 121 -12 490 ...
data <- data.frame(Tbox[,c(1,4,9, 12, 15, 16)])
labs <- c("% 2-point shots made",
          "% 3-point shots made",
          "% free throws made",
          'Points')

# Players
str(Pbox)
'data.frame':   605 obs. of  22 variables:
 $ Team  : chr  "Atlanta Hawks" "Atlanta Hawks" "Atlanta Hawks" "Atlanta Hawks" ...
 $ Player: chr  "Taurean Prince" "Dennis Schroder" "Kent Bazemore" "John Collins" ...
 $ GP    : int  82 67 65 74 62 52 46 67 53 54 ...
 $ MIN   : int  2464 2078 1789 1785 1542 1210 1175 1167 1060 1014 ...
 $ PTS   : int  1158 1301 836 777 617 591 501 445 405 338 ...
 $ P2M   : int  239 424 176 298 200 107 123 143 81 63 ...
 $ P2A   : int  518 884 402 498 336 238 231 310 145 161 ...
 $ P2p   : num  46.1 48 43.8 59.8 59.5 ...
 $ P3M   : int  176 76 108 16 50 92 61 20 62 46 ...
 $ P3A   : int  457 262 274 47 141 247 170 80 167 124 ...
 $ P3p   : num  38.5 29 39.4 34 35.5 ...
 $ FTM   : int  152 225 160 133 67 101 72 99 57 74 ...
 $ FTA   : int  180 265 201 186 86 109 90 141 62 92 ...
 $ FTp   : num  84.4 84.9 79.6 71.5 77.9 ...
 $ OREB  : int  50 44 25 176 100 14 74 22 56 9 ...
 $ DREB  : int  339 164 223 365 389 86 177 72 174 91 ...
 $ AST   : int  214 417 228 98 90 103 51 206 51 163 ...
 $ TOV   : int  191 183 157 105 86 54 43 84 42 66 ...
 $ STL   : int  85 72 100 47 40 46 44 34 31 35 ...
 $ BLK   : int  42 6 45 80 51 3 17 10 27 6 ...
 $ PF    : int  168 147 147 215 162 41 92 116 80 82 ...
 $ PM    : int  -366 -277 -162 -220 -158 -189 -75 -36 -77 -104 ...
# Players
str(Pbox)
'data.frame':   605 obs. of  22 variables:
 $ Team  : chr  "Atlanta Hawks" "Atlanta Hawks" "Atlanta Hawks" "Atlanta Hawks" ...
 $ Player: chr  "Taurean Prince" "Dennis Schroder" "Kent Bazemore" "John Collins" ...
 $ GP    : int  82 67 65 74 62 52 46 67 53 54 ...
 $ MIN   : int  2464 2078 1789 1785 1542 1210 1175 1167 1060 1014 ...
 $ PTS   : int  1158 1301 836 777 617 591 501 445 405 338 ...
 $ P2M   : int  239 424 176 298 200 107 123 143 81 63 ...
 $ P2A   : int  518 884 402 498 336 238 231 310 145 161 ...
 $ P2p   : num  46.1 48 43.8 59.8 59.5 ...
 $ P3M   : int  176 76 108 16 50 92 61 20 62 46 ...
 $ P3A   : int  457 262 274 47 141 247 170 80 167 124 ...
 $ P3p   : num  38.5 29 39.4 34 35.5 ...
 $ FTM   : int  152 225 160 133 67 101 72 99 57 74 ...
 $ FTA   : int  180 265 201 186 86 109 90 141 62 92 ...
 $ FTp   : num  84.4 84.9 79.6 71.5 77.9 ...
 $ OREB  : int  50 44 25 176 100 14 74 22 56 9 ...
 $ DREB  : int  339 164 223 365 389 86 177 72 174 91 ...
 $ AST   : int  214 417 228 98 90 103 51 206 51 163 ...
 $ TOV   : int  191 183 157 105 86 54 43 84 42 66 ...
 $ STL   : int  85 72 100 47 40 46 44 34 31 35 ...
 $ BLK   : int  42 6 45 80 51 3 17 10 27 6 ...
 $ PF    : int  168 147 147 215 162 41 92 116 80 82 ...
 $ PM    : int  -366 -277 -162 -220 -158 -189 -75 -36 -77 -104 ...
data <- Pbox
data <- subset(Pbox, Team =="Boston Celtics" & MIN>=500)
data <- subset(Pbox, Team =="Boston Celtics" & MIN>=500)
data <- data.frame(data[, c(1, 2, 5, 8, 11, 14)])
data <- subset(Pbox, Team =="Boston Celtics" & MIN>=500)
data <- data.frame(data[, c(1, 2, 5, 8, 11, 14)])
labs <- c("% 2-point shots made",
          "% 3-point shots made",
          "% free throws made",
          "Points")

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLg0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQojYmFza2V0YmFsbCBzaG90Y2hhcnQgYW5hbHlzaXMNCmxpYnJhcnkoQmFza2V0YmFsbEFuYWx5emVSKQ0KUGJQIDwtIFBiUG1hbmlwdWxhdGlvbihQYlAuQkRCKQ0KaGVhZChQYlApDQpgYGANCg0KXA0KXA0KXA0KDQpgYGB7cn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYHsjIGZvciBzdGVwaGVuIGN1cnJ5fSBzdWJkYXRhIDwtIHN1YnNldChQYlAsIHBsYXllcj09IlN0ZXBoZW4gQ3VycnkiKSBzdWJkYXRhJHh4IDwtIHN1YmRhdGEkb3JpZ2luYWxfeC8xMCBzdWJkYXRhJHl5IDwtIHN1YmRhdGEkb3JpZ2luYWxfeS8xMC00MS43NWANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQpgYGB7cn0NCmhlYWQoUGJQKQ0KYGBgDQoNCmBgYHtyfQ0KdGltZS50czwtdHMoUGJQJHRlYW0pDQpwbG90KHRpbWUudHMpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQojIHBsb3R0aW5nIHRlYW0gd2l0aCB0aGVpciBzaG90eXBlcw0KcGxvdChQYlAkdGVhbSxQYlAkU2hvdFR5cGUseGxhYj0idGVhbXMiLCB5bGFiPSJTaG90eXBlIixjb2w9Im9yYW5nZSIpDQpgYGANCg0KYGBge3J9DQojIHBsb3R0aW5nIGhpc3RvZ3JhbSBvZiBzaG90IGRpc3RhbmNlDQp4PVBiUCRzaG90X2Rpc3RhbmNlDQpoaXN0KHgseGxhYj0ic2hvdCBkaXN0YW5jZSIseWxhYj0iZnJlcXVlbmN5Iixjb2wgPSAieWVsbG93IikNCg0KDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGdnYW5pbWF0ZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2FwbWluZGVyKQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoZHBseXIpDQoNCg0KIyBwbG90dGluZyBob21lIGFuZCBhd2F5IHNjb3JlcyBvZiBwbGF5ZXIgc3RlcGhlbiBjdXJyeQ0Kc3ViZGF0YTEgPC0gc3Vic2V0KFBiUCwgcGxheWVyPT0iU3RlcGhlbiBDdXJyeSIpDQojZ2dwbG90KGRhdGE9c3ViZGF0YTEsbWFwcGluZz1hZXMoeD1ob21lX3Njb3JlLHk9YXdheV9zY29yZSxjb2w9ImJsdWUiKSkrDQogIyBnZW9tX3BvaW50KHNpemU9MSkNCmdhcG1pbmRlcg0KDQpncmFwaDEgPSBnYXBtaW5kZXIgJT4lDQogIGdncGxvdChhZXMoeD1nZHBQZXJjYXAseT1saWZlRXhwLGNvbG9yPWNvbnRpbmVudCxzaXplPXBvcCkpKyANCiAgZ2VvbV9wb2ludCgpDQoNCmdyYXBoMS5hbmltYXRpb24gPSBncmFwaDEgKyB0cmFuc2l0aW9uX3RpbWUoeWVhcikNCg0KZ3JhcGgxDQoNCg0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgcGxvdHRpbmcgaG9tZSBhbmQgYXdheSBzY29yZXMgYW5kIGFsc28gc2hvd2luZyB0aGUgcmVzdWx0cw0KZ2dwbG90KGRhdGE9c3ViZGF0YTEsbWFwcGluZz1hZXMoeD1ob21lX3Njb3JlLHk9YXdheV9zY29yZSxjb2xvdXI9cmVzdWx0KSkrDQogIGdlb21fcG9pbnQoKQ0KYGBgDQoNCmBgYHtyfQ0KDQoNCmdncGxvdChkYXRhPXN1YmRhdGExLG1hcHBpbmc9YWVzKHg9aG9tZV9zY29yZSx5PWF3YXlfc2NvcmUsY29sb3VyPXJlc3VsdCkpKw0KICBnZW9tX2JveHBsb3QoKQ0KDQpgYGANCg0KYGBge3J9DQpzaG90Y2hhcnQoZGF0YT1zdWJkYXRhLCB4PSJ4eCIsIHk9Inl5Iiwgc2NhdHRlciA9IFQsDQogICAgICAgICAgcHQuY29sPSdibHVlJywNCiAgICAgICAgICBiZy5jb2w9J3llbGxvdycpDQpgYGANCg0KYGBge3J9DQpzaG90Y2hhcnQoZGF0YT1zdWJkYXRhLCB4PSJ4eCIsIHk9Inl5Iiwgc2NhdHRlciA9IFQsDQogICAgICAgICAgej0ncmVzdWx0JywNCiAgICAgICAgICBiZy5jb2w9J2JsYWNrJywNCiAgICAgICAgICBjb3VydGxpbmUuY29sPSd3aGl0ZScsDQogICAgICAgICAgcGFsZXR0ZT0naG90JykNCmBgYA0KDQpgYGB7cn0NCnNob3RjaGFydChkYXRhPXN1YmRhdGEsIHg9Inh4IiwgeT0ieXkiLCBzY2F0dGVyID0gVCwNCiAgICAgICAgICBudW0uc2VjdCA9IDUsDQogICAgICAgICAgdHlwZT0nc2VjdG9ycycsDQogICAgICAgICAgej0ncGxheWxlbmd0aCcpDQpgYGANCg0KYGBge3J9DQpzaG90Y2hhcnQoZGF0YT1zdWJkYXRhLCB4PSJ4eCIsIHk9Inl5Iiwgc2NhdHRlciA9IEYsDQogICAgICAgICAgbnVtLnNlY3QgPSA1LA0KICAgICAgICAgIHR5cGU9J3NlY3RvcnMnLA0KICAgICAgICAgIHo9J3BsYXlsZW5ndGgnLA0KICAgICAgICAgIHJlc3VsdD0ncmVzdWx0JykNCmBgYA0KDQpgYGB7cn0NCiMgZm9yIEtldmluIER1cmFudA0Kc3ViZGF0YSA8LSBzdWJzZXQoUGJQLCBwbGF5ZXI9PSJLZXZpbiBEdXJhbnQiKQ0Kc3ViZGF0YSR4eCA8LSBzdWJkYXRhJG9yaWdpbmFsX3gvMTANCnN1YmRhdGEkeXkgPC0gc3ViZGF0YSRvcmlnaW5hbF95LzEwLTQxLjc1DQpzdWJkYXRhDQpgYGANCg0KYGBge3J9DQoNCnNob3RjaGFydChkYXRhPXN1YmRhdGEsIHg9Inh4IiwgeT0ieXkiLCBzY2F0dGVyID0gVCwNCiAgICAgICAgICBwdC5jb2w9J2JsdWUnLA0KICAgICAgICAgIGJnLmNvbD0neWVsbG93JykNCg0KDQpgYGANCg0KYGBge3J9DQpzaG90Y2hhcnQoZGF0YT1zdWJkYXRhLCB4PSJ4eCIsIHk9Inl5Iiwgc2NhdHRlciA9IFQsDQogICAgICAgICAgej0ncmVzdWx0JywNCiAgICAgICAgICBiZy5jb2w9J2JsYWNrJywNCiAgICAgICAgICBjb3VydGxpbmUuY29sPSd3aGl0ZScsDQogICAgICAgICAgcGFsZXR0ZT0naG90JykNCmBgYA0KDQpgYGB7cn0NCnNob3RjaGFydChkYXRhPXN1YmRhdGEsIHg9Inh4IiwgeT0ieXkiLCBzY2F0dGVyID0gVCwNCiAgICAgICAgICBudW0uc2VjdCA9IDUsDQogICAgICAgICAgdHlwZT0nc2VjdG9ycycsDQogICAgICAgICAgej0ncGxheWxlbmd0aCcpDQpgYGANCg0KYGBge3J9DQpzaG90Y2hhcnQoZGF0YT1zdWJkYXRhLCB4PSJ4eCIsIHk9Inl5Iiwgc2NhdHRlciA9IEYsDQogICAgICAgICAgbnVtLnNlY3QgPSA1LA0KICAgICAgICAgIHR5cGU9J3NlY3RvcnMnLA0KICAgICAgICAgIHo9J3BsYXlsZW5ndGgnLA0KICAgICAgICAgIHJlc3VsdD0ncmVzdWx0JykNCmBgYA0KDQpgYGB7cn0NCiMgTmV0d29yayBhbmFseXNpcyBvZiBwbGF5ZXJzIGludGVyYWN0aW9ucw0KDQpsaWJyYXJ5KEJhc2tldGJhbGxBbmFseXplUikNCm9wdGlvbnMoZ2dyZXBlbC5tYXgub3ZlcmxhcHMgPSBJbmYpDQpQYlAgPC0gUGJQbWFuaXB1bGF0aW9uKFBiUC5CREIpDQp0YWJsZShQYlAkdGVhbSkNCnN1YmRhdGEgPC0gc3Vic2V0KFBiUCwgdGVhbSA9PSAiR1NXIikNCm5ldCA8LSBhc3Npc3RuZXQoc3ViZGF0YSkNCg0KbmV0JGFzc2lzdFRhYmxlDQpuZXQkbm9kZVN0YXRzDQpuZXQkYXNzaXN0TmV0DQoNCnNldC5zZWVkKDEyMykNCg0KDQpgYGANCg0KYGBge3J9DQpwbG90KG5ldCwNCiAgICAgbm9kZS5zaXplPSdBU1RQVFMnLA0KICAgICBub2RlLmNvbD0nRkdQVFNfQVNUJykNCg0KDQpgYGANCg0KYGBge3J9DQpwbG90KG5ldCwNCiAgICAgbm9kZS5zaXplPSdBU1RQVFMnLA0KICAgICBub2RlLmNvbD0nRkdQVFNfQVNUJywNCiAgICAgbGF5b3V0ID0gJ2NpcmNsZScsDQogICAgIGVkZ2UudGhyID0gMjApDQpgYGANCg0KYGBge3J9DQoNCiMgTkJBIFRlYW0gJiBQbGF5ZXIgUGVyZm9ybWFuY2UgQW5hbHlzaXMNCg0KbGlicmFyeShCYXNrZXRiYWxsQW5hbHl6ZVIpDQpgYGANCg0KYGBge3J9DQojIFRlYW1zDQpzdHIoVGJveCkNCmRhdGEgPC0gZGF0YS5mcmFtZShUYm94WyxjKDEsNCw5LCAxMiwgMTUsIDE2KV0pDQpsYWJzIDwtIGMoIiUgMi1wb2ludCBzaG90cyBtYWRlIiwNCiAgICAgICAgICAiJSAzLXBvaW50IHNob3RzIG1hZGUiLA0KICAgICAgICAgICIlIGZyZWUgdGhyb3dzIG1hZGUiLA0KICAgICAgICAgICdQb2ludHMnKQ0KYGBgDQoNCmBgYHtyfQ0KDQpidWJibGVwbG90KGRhdGEsIGlkPSJUZWFtIiwgDQogICAgICAgICAgIHg9IlAycCIsIA0KICAgICAgICAgICB5PSJQM3AiLCANCiAgICAgICAgICAgY29sPSJGVHAiLA0KICAgICAgICAgICBzaXplID0gJ1BUUycsDQogICAgICAgICAgIGxhYmVscz1sYWJzKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQbGF5ZXJzDQpzdHIoUGJveCkNCmRhdGEgPC0gUGJveA0KZGF0YSA8LSBzdWJzZXQoUGJveCwgVGVhbSA9PSJCb3N0b24gQ2VsdGljcyIgJiBNSU4+PTUwMCkNCmRhdGEgPC0gZGF0YS5mcmFtZShkYXRhWywgYygxLCAyLCA1LCA4LCAxMSwgMTQpXSkNCmxhYnMgPC0gYygiJSAyLXBvaW50IHNob3RzIG1hZGUiLA0KICAgICAgICAgICIlIDMtcG9pbnQgc2hvdHMgbWFkZSIsDQogICAgICAgICAgIiUgZnJlZSB0aHJvd3MgbWFkZSIsDQogICAgICAgICAgIlBvaW50cyIpDQoNCmBgYA0KDQpgYGB7cn0NCmBgYA0KDQpgYGB7cn0NCmJ1YmJsZXBsb3QoZGF0YSwgaWQ9IlBsYXllciIsIA0KICAgICAgICAgICB4PSJQMnAiLCANCiAgICAgICAgICAgeT0iUDNwIiwgDQogICAgICAgICAgIGNvbD0iRlRwIiwNCiAgICAgICAgICAgc2l6ZT0iUFRTIiwNCiAgICAgICAgICAgbGFiZWxzPWxhYnMsDQogICAgICAgICAgIHRleHQuc2l6ZT0yKQ0KYGBgDQoNCmBgYHtyfQ0KIyBjb21wYXJlIHBsYXllcnMgZnJvbSAyIHRlYW1zDQoNCiMgb3B0aW9ucyhnZ3JlcGVsLm1heC5vdmVybGFwcyA9IEluZikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dyZXBlbCkNCmRhdGEgPC0gUGJveA0KZGF0YSA8LSBzdWJzZXQoUGJveCwgVGVhbSA9PSJCb3N0b24gQ2VsdGljcyIgfCBUZWFtPT0nR29sZGVuIFN0YXRlIFdhcnJpb3JzJyAmICBNSU4+PTUwMCkNCmRhdGEgPC0gZGF0YS5mcmFtZShkYXRhWywgYygxLCAyLCA1LCA4LCAxMSwgMTQpXSkNCmxhYnMgPC0gYygiJSAyLXBvaW50IHNob3RzIG1hZGUiLA0KICAgICAgICAgICIlIDMtcG9pbnQgc2hvdHMgbWFkZSIsDQogICAgICAgICAgIiUgZnJlZSB0aHJvd3MgbWFkZSIsDQogICAgICAgICAgIlBvaW50cyIpDQoNCg0KYnViYmxlcGxvdChkYXRhLCBpZD0iUGxheWVyIiwgDQogICAgICAgICAgIHg9IlAycCIsIA0KICAgICAgICAgICB5PSJQM3AiLCANCiAgICAgICAgICAgY29sPSJGVHAiLA0KICAgICAgICAgICBzaXplPSJQVFMiLA0KICAgICAgICAgICBsYWJlbHM9bGFicywNCiAgICAgICAgICAgdGV4dC5zaXplPTIpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg==